package com.njupt.yanglonglong.report.demo.controller;

import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.njupt.yanglonglong.report.demo.common.Result;
import com.njupt.yanglonglong.report.demo.config.minio.MinioProperties;
import com.njupt.yanglonglong.report.demo.dto.CourseDto;
import com.njupt.yanglonglong.report.demo.dto.ExperimentInfoDto;
import com.njupt.yanglonglong.report.demo.dto.StudentExperimentInfo;
import com.njupt.yanglonglong.report.demo.entity.Experiment;
import com.njupt.yanglonglong.report.demo.entity.RAppliedExperiment;
import com.njupt.yanglonglong.report.demo.entity.RUser;
import com.njupt.yanglonglong.report.demo.service.ExperimentService;
import com.njupt.yanglonglong.report.demo.service.RAppliedExperimentService;
import com.njupt.yanglonglong.report.demo.service.RAppliedStudentService;
import com.njupt.yanglonglong.report.demo.utils.MinIoUtil;
import com.njupt.yanglonglong.report.demo.utils.RedisUtil;
import com.njupt.yanglonglong.report.demo.utils.StringParseUtil;
import com.njupt.yanglonglong.report.demo.vo.ExperimentVO;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletRequest;
import java.io.UnsupportedEncodingException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;

/**
 * @Author yangllong
 * @Date 2021/4/28 15:36
 */
@CrossOrigin
@Slf4j
@RestController
public class ExperimentController {
    @Autowired
    private ExperimentService experimentService;
    @Autowired
    private RedisUtil redisUtil;
    @Autowired
    private MinioProperties minioProperties;
    @Autowired
    private RAppliedStudentService appliedStudentService;

    @Autowired
    private RAppliedExperimentService rAppliedExperimentService;

    @PostMapping("/getExperimentList")
    @Deprecated
    public Result getExperimentList(HttpServletRequest request) {
        JSONObject res = new JSONObject();
        String token = request.getHeader("Authorization");
        RUser user = redisUtil.getUser(token);
        if (user == null) {
            res.put("msg", "用户权限校验失败，请先登录");
            return Result.error(res);
        }
        String teacherId = user.getUserId();
        List<ExperimentVO> experimentList = experimentService.queryExperiment();
        List<ExperimentVO> teacherExperimentList = new ArrayList<>();
        experimentList.forEach((ExperimentVO e) -> {
            if (e.getTeacherId() != null && e.getTeacherId().equals(teacherId)) {
                teacherExperimentList.add(e);
            }
        });
        res.put("msg", "实验列表获取成功");
        res.put("experimentList", teacherExperimentList);
        res.put("total", teacherExperimentList.size());
        return Result.success(res);
    }

    @PostMapping("/getExperimentList2")
    public Result getExperimentList2(HttpServletRequest request) {
        JSONObject res = new JSONObject();
        String token = request.getHeader("Authorization");
        RUser user = redisUtil.getUser(token);
        if (user == null) {
            return Result.unauthorized();
        }
        List<ExperimentVO> experimentList = experimentService.queryExperiment();
        res.put("msg", "实验列表获取成功");
        res.put("experimentList", experimentList);
        res.put("total", experimentList.size());
        return Result.success(res);
    }

    @PostMapping("/getExperimentListByStuId")
    public Result getExperimentListByStuId(HttpServletRequest request) {
        JSONObject res = new JSONObject();
        String token = request.getHeader("Authorization");
        RUser user = redisUtil.getUser(token);
        if (user == null) {
            return Result.unauthorized();
        }
        String stuId = user.getUserId();
        List<CourseDto> courses = appliedStudentService.getCoursesByStuId(stuId);
        List<ExperimentInfoDto> experiments = new ArrayList<>();
        for (CourseDto course :
                courses) {
            String courseId = course.getCourseId();
            String teacherId = course.getTeacherId();
            List<ExperimentInfoDto> experimentList = rAppliedExperimentService
                    .queryOpenedExperimentList(courseId, teacherId);
            experiments.addAll(experimentList);
        }
        res.put("msg", "实验列表获取成功");
        res.put("courses", courses);
        res.put("experiments", experiments);
        res.put("courseNum", courses.size());
        res.put("experNum", experiments.size());
        return Result.success(res);
    }

    @PostMapping("/uploadReportTemplate")
    public Result uploadReportTemplate(HttpServletRequest request, String experId, MultipartFile file) {
        JSONObject res = new JSONObject();
        String token = request.getHeader("Authorization");
        RUser user = redisUtil.getUser(token);
        if (user == null) {
            res.put("msg", "用户权限校验失败，请先登录");
            return Result.error(res);
        }
        String teacherId = user.getUserId();
        String fileName = MinIoUtil.upload(minioProperties.getBucketName(), file, user.getUserId());
        log.info("[文件名]" + fileName);
        rAppliedExperimentService.uploadReportTemplate(teacherId, experId, fileName);
        res.put("msg", "上传模板成功");
        return Result.success(res);
    }

    @PostMapping("/deleteReportTemplate")
    public Result deleteReportTemplate(HttpServletRequest request, @RequestBody Experiment experiment) throws UnsupportedEncodingException {
        JSONObject res = new JSONObject();
        String token = request.getHeader("Authorization");
        RUser user = redisUtil.getUser(token);
        if (user == null) {
            res.put("msg", "用户权限校验失败，请先登录");
            return Result.error(res);
        }
        String teacherId = user.getUserId();
        String filename = StringParseUtil.getFileNameFromUrl(experiment.getReportTemplate());
        MinIoUtil.deleteFile(minioProperties.getBucketName(), filename);
        rAppliedExperimentService.uploadReportTemplate(teacherId, experiment.getExperId(), null);
        log.info("【删除文件：" + filename + "成功】");
        res.put("msg", "删除模板成功");
        return Result.success(res);
    }


    /**
     * 管理员查询所有的实验
     *
     * @param request 校验
     * @return experimentVOList
     */
    @RequestMapping("/queryAllExperiment")
    public Result queryAllExperiment(HttpServletRequest request) {
        JSONObject res = new JSONObject();
        String token = request.getHeader("Authorization");
        RUser user = redisUtil.getUser(token);
        if (user == null) {
            res.put("msg", "用户权限校验失败，请先登录");
            return Result.error(res);
        }
        List<ExperimentVO> experimentVOList = experimentService.queryExperiment();
        if (experimentVOList == null) {
            res.put("msg", "没有查询到实验");
            log.error("/queryAllExperiment查询不到");
            return Result.error(res);
        }
        res.put("data", experimentVOList);
        return Result.success(res);
    }

    /**
     * 管理员端添加实验，接收experiment
     *
     * @param request    user
     * @param experiment Experiment
     * @return isSuccess
     */
    @RequestMapping("/addExperiment")
    public Result addExperiment(HttpServletRequest request, @RequestBody Experiment experiment) {
        String token = request.getHeader("Authorization");
        RUser user = redisUtil.getUser(token);
        log.info("/addExperiment接到请求，user：" + user + "Experiment:" + experiment);
        JSONObject res = new JSONObject();
        if (experiment.getExperId().length() > 10) {
            res.put("msg", "实验编号太长，请输入10位以下的编号");
            return Result.error(res);
        }
        boolean save = experimentService.save(experiment);
        if (!save) {
            log.error("/addExperiment添加实验失败");
            res.put("msg", "添加失败");
            return Result.error(res);
        }
        res.put("msg", "添加成功");
        return Result.success(res);
    }

    /**
     * 删除实验
     *
     * @param request      用户
     * @param experimentVO 实验信息
     * @return isSuccess
     */
    @RequestMapping("/deleteExperiment")
    public Result deleteExperiment(HttpServletRequest request, @RequestBody ExperimentVO experimentVO) {
        String token = request.getHeader("Authorization");
        RUser user = redisUtil.getUser(token);
        log.info("/deleteExperiment接到请求，user：" + user + "data:" + experimentVO);
        JSONObject res = new JSONObject();
        String experId = experimentVO.getExperId();
        QueryWrapper<RAppliedExperiment> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("exper_id", experId);
        List<RAppliedExperiment> list = rAppliedExperimentService.list(queryWrapper);
        if (list.size() != 0) {
            res.put("msg", "无法删除实验，因为已经有老师选择了实验");
            log.error("/deleteExperiment无法删除实验，因为已经有老师选择了实验");
            return Result.error(res);
        }
        QueryWrapper<Experiment> queryWrapper1 = new QueryWrapper<>();
        queryWrapper1.eq("id", experimentVO.getId());
        if (!experimentService.remove(queryWrapper1)) {
            res.put("msg", "删除失败");
            log.error("/deleteExperiment删除失败 user{} experimentVO{}", user, experimentVO);
            return Result.error(res);
        }
        res.put("msg", "删除成功");
        return Result.success(res);
    }


    /**
     * 学生查询课程的实验列表
     *
     * @param request stuId
     * @param map     courseId
     * @return studentExperimentInfoList
     */
    @RequestMapping("/queryStudentExperiment")
    public Result queryStudentExperiment(HttpServletRequest request, @RequestBody HashMap<String, String> map) {
        String token = request.getHeader("Authorization");
        RUser user = redisUtil.getUser(token);
        JSONObject res = new JSONObject();
        log.info("/queryStudentExperiment接到请求，user：" + user + "data:" + map);
        //防止判空空指针异常
        List<StudentExperimentInfo> studentExperimentInfoList;
        studentExperimentInfoList = experimentService.queryStudentExperimentList(map.get("courseId"), user.getUserId());
        if (studentExperimentInfoList == null) {
            res.put("msg", "没有查询到已选课程的开设实验");
            return Result.error(res);
        }
        res.put("data", studentExperimentInfoList);
        return Result.success(res);
    }

    /**
     * 根据课程id获取实验列表
     *
     * @param request r
     * @param map     course
     * @return expList
     */
    @PostMapping("/getExperimentListByCourseId")
    public Result getExperimentListByCourseId(HttpServletRequest request, @RequestBody HashMap<String, String> map) {
        JSONObject res = new JSONObject();
        String token = request.getHeader("Authorization");
        RUser user = redisUtil.getUser(token);
        if (user == null) {
            return Result.unauthorized();
        }
        String courseId = map.get("courseId");
        List<Experiment> expList = experimentService.getExperimentListByCourseId(courseId);
        res.put("experList", expList);
        return Result.success(res);
    }

}
